#import "ORGSSGLView.h"

static ORGSSGLView *currentView;

static CVReturn RGOGLVDisplayLinkCallback ( CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, 
										   CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext ) {
    CVReturn result = [(ORGSSGLView *) displayLinkContext getFrameForTime: outputTime];
    return result;
}

@implementation ORGSSGLView

+ (ORGSSGLView *) currentView {
	return currentView;
}

- (id) initWithFrame: (NSRect) frameRect {
	NSOpenGLPixelFormatAttribute attributes [] = {
		NSOpenGLPFADoubleBuffer,
		NSOpenGLPFAMultisample,
		NSOpenGLPFASamples, 16,
		NSOpenGLPFAColorSize, 96,
		NSOpenGLPFAAlphaSize, 32,
		NSOpenGLPFADepthSize, 32,
		0
	};
	
	NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes: attributes];
	self = [super initWithFrame: frameRect pixelFormat: format];
	[format release];
	
	if ( self != nil ) {
	}
	
	return self;
}

- (void) prepareOpenGL {
	[super prepareOpenGL];
	
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	
	NSRect bounds = [self bounds];
	glViewport(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 640, 480, 0, -1.0, 1.0);
	
    GLint swapInt = 1;
    [[self openGLContext] setValues: &swapInt forParameter: NSOpenGLCPSwapInterval]; 
	
    CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
	
    CVDisplayLinkSetOutputCallback(displayLink, &RGOGLVDisplayLinkCallback, self);
	
    CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
    CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
    CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
	
    CVDisplayLinkStart(displayLink);
}

- (void) reshape {
	NSRect bounds = [self bounds];
	glViewport(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 640, 480, 0, -1.0, 1.0);
}

- (CVReturn) getFrameForTime: (const CVTimeStamp *) time {
	[self display];
	
	return kCVReturnSuccess;
}

- (void) drawRect: (NSRect) dirtyRect {
	[[self openGLContext] makeCurrentContext];
	
	glClear(GL_COLOR_BUFFER_BIT);
	
	[[self openGLContext] flushBuffer];
}

@end
